﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class HengLianLiPipeNew : IExternalCommand
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			if (HengLianLiPipeNew.hWndRevit == null)
			{
				HengLianLiPipeNew.hWndRevit = new YJKWindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			UIApplication application = commandData.Application;
			Autodesk.Revit.ApplicationServices.Application application2 = application.Application;
			Document document = application.ActiveUIDocument.Document;
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			List<ViewType> viewTypes = YJKRevitTools.ListViewNeed(2);
			if (!YJKRevitTools.ViewCheck(activeUIDocument, viewTypes))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			SetTeeFittingForm setTeeFittingForm = new SetTeeFittingForm();
			setTeeFittingForm.Show(HengLianLiPipeNew.hWndRevit);
			Result result;
			try
			{
				transaction = new Transaction(document, "横管连接立管");
				transaction.Start();
				ISelectionFilter selectionFilter = new RiserPipeFilter();
				ISelectionFilter selectionFilter2 = new HoriPipeFilter();
				Selection selection = activeUIDocument.Selection;
				ConnectPipeManage connectPipeManage = new ConnectPipeManage();
				for (;;)
				{
					try
					{
						Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter2, "请选择要连接的横管");
						Reference reference2 = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "请选择要连接的立管");
						Pipe pipe = document.GetElement(reference) as Pipe;
						Pipe pipe2 = document.GetElement(reference2) as Pipe;
						SearchBranch searchBranch = new SearchBranch(pipe2);
						searchBranch.DoSearch();
						ElementNode listRoot = searchBranch.GetListRoot();
						List<ElementNode> list = new List<ElementNode>();
						this.GetAllElemNodeReference(listRoot, ref list);
						List<Pipe> list2 = new List<Pipe>();
						Dictionary<Pipe, double> dictionary = new Dictionary<Pipe, double>();
						foreach (ElementNode elementNode in list)
						{
							Pipe pipe3 = elementNode.Element as Pipe;
							Line curve = (pipe3.Location as LocationCurve).Curve as Line;
							double z = ((curve.GetEndPoint(0) + curve.GetEndPoint(1)) / 2.0).Z;
							dictionary.Add(pipe3, z);
						}
						foreach (KeyValuePair<Pipe, double> keyValuePair in from i in dictionary
						orderby i.Value descending
						select i)
						{
							list2.Add(keyValuePair.Key);
						}
						bool flag = false;
						Line curve2 = (pipe.Location as LocationCurve).Curve as Line;
						XYZ hyendPoint = curve2.GetEndPoint(0);
						XYZ hyendPoint2 = curve2.GetEndPoint(1);
						foreach (Pipe pipe4 in list2)
						{
							Line line = (pipe4.Location as LocationCurve).Curve as Line;
							XYZ hyendPoint3 = line.GetEndPoint(0);
							XYZ hyendPoint4 = line.GetEndPoint(1);
							XYZ dlineP = YJKRevitTools.GetDLineP(hyendPoint, hyendPoint2, hyendPoint3, hyendPoint4);
							if (new YJKLine(line).IsPointOnLine(dlineP))
							{
								pipe2 = pipe4;
								flag = true;
								break;
							}
						}
						if (!flag)
						{
							Line curve3 = (list2.ElementAt(0).Location as LocationCurve).Curve as Line;
							if (((curve3.GetEndPoint(0).Z - curve3.GetEndPoint(1).Z > 0.0) ? curve3.GetEndPoint(0) : curve3.GetEndPoint(1)).Z > hyendPoint.Z)
							{
								int index = list2.Count - 1;
								pipe2 = list2.ElementAt(index);
							}
						}
						YJKPipeConnectorHelper hypipeConnectorHelper = new YJKPipeConnectorHelper();
						string text = "";
						string teeName = setTeeFittingForm.GetTeeName();
						FamilySymbol familySymbolByName = connectPipeManage.GetFamilySymbolByName(teeName, document, ref text);
						if (text != "")
						{
							YJKMessageBox.Show(text);
							continue;
						}
						int connStyle = setTeeFittingForm.GetConnStyle();
						int connDiameter = setTeeFittingForm.GetConnDiameter();
						if (connStyle == 1 || connStyle == 2 || connStyle == 3)
						{
							hypipeConnectorHelper.TPipeConnectRPipe(pipe2, pipe, familySymbolByName, connStyle, ref text, true, (double)connDiameter);
						}
						else
						{
							hypipeConnectorHelper.TPipeConnectRPipe(pipe2, pipe, document, familySymbolByName, true, ref text, true, (double)connDiameter);
						}
						if (text != "")
						{
							YJKMessageBox.Show(text);
						}
						continue;
					}
					catch (Autodesk.Revit.Exceptions.OperationCanceledException)
					{
						setTeeFittingForm.Close();
					}
					break;
				}
				transaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				setTeeFittingForm.Close();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				this.EndTransation(transaction, false);
				setTeeFittingForm.Close();
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				this.EndTransation(transaction, true);
			}
			return result;
		}

		private List<ElementNode> GetAllElemNodeReference(ElementNode eNode, ref List<ElementNode> listENode)
		{
			if (eNode == null)
			{
				return listENode;
			}
			if (eNode.Element is Pipe)
			{
				Line curve = ((eNode.Element as Pipe).Location as LocationCurve).Curve as Line;
				curve.GetEndPoint(0);
				XYZ xyz = (curve.GetEndPoint(0) + curve.GetEndPoint(1)) / 2.0;
				Pipe pipe = eNode.Element as Pipe;
				Line curve2 = (pipe.Location as LocationCurve).Curve as Line;
				XYZ xyz2 = (curve2.GetEndPoint(0) + curve2.GetEndPoint(1)) / 2.0;
				if (YJKRevitTools.isRiserPipe(pipe) && Math.Abs(xyz2.X - xyz.X) < 0.001 && Math.Abs(xyz2.Y - xyz.Y) < 0.001 && (xyz2.Z < xyz.Z || xyz2.IsAlmostEqualTo(xyz)))
				{
					listENode.Add(eNode);
				}
			}
			if (eNode.Next != null)
			{
				this.GetAllElemNodeReference(eNode.Next, ref listENode);
			}
			if (eNode.SubElementNode != null)
			{
				foreach (ElementNode eNode2 in eNode.SubElementNode)
				{
					this.GetAllElemNodeReference(eNode2, ref listENode);
				}
			}
			return listENode;
		}

		private void EndTransation(Transaction tran, bool beSure)
		{
			if (tran != null)
			{
				TransactionStatus status = tran.GetStatus();
				if ((int)status == 1)
				{
					if (beSure)
					{
						tran.Commit();
						return;
					}
					tran.RollBack();
					return;
				}
				else if ((int)status == 5)
				{
					tran.RollBack();
				}
			}
		}

		public static YJKWindowHandle hWndRevit;
	}
}
